home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 09 - 1993 / 09.03 Mar 93 / Voxels / Voxel.c next >
Encoding:
C/C++ Source or Header  |  1992-10-12  |  7.1 KB  |  311 lines  |  [TEXT/KAHL]

  1. #include <Palettes.h>
  2. #include <SANE.h>
  3. #include <QDOffscreen.h>
  4.  
  5. /* size of the voxel data */
  6. #define volSize     128
  7. /* half the size of voxel data */
  8. #define halfVolSize    64
  9. /* the radius of the sphere */
  10. #define sphere_r    60
  11. /* sphere_r*sphere_r */
  12. #define volumeMag    3600.0
  13. /* sqrt(3.0)*sphere_r */
  14. #define sqrt3r        103.9230
  15. /* sphere_r*sqrt(6+2*sqrt(3)) */
  16. #define rsqrt6        184.5827
  17.  
  18. /* resource numbers for the window, palette and menus */
  19. #define windowRscr 128
  20. #define paletteRscr 128
  21.  
  22. #define appleID 128
  23. #define appleM 1
  24. #define appleAbout 1
  25.  
  26. #define fileID 129
  27. #define fileM 2
  28. #define fileQuit 1
  29.  
  30. #define editID 130
  31. #define editM 3
  32. #define editUndo 1
  33. #define editCut 3
  34. #define editCopy 4
  35. #define editPaste 5
  36. #define editClear 6
  37.  
  38. #define sleepTicks 30
  39.  
  40. #define aboutDialog 128
  41.  
  42. /* these constants define the Phong shading */
  43. /* ambient reflection coefficient */
  44. #define ambientReflCoef    0.1
  45. /* depth cueing coefficient */
  46. #define depthCueCoef    1.0
  47. /* diffuse reflection coefficient */
  48. #define diffReflCoef    5.0
  49. /* specular reflection coefficient */
  50. #define specReflCoef    5.0
  51. /* first light source intensity */
  52. #define light    1.0
  53. /* coefficient to approx highlight */
  54. #define highlightCoef    30
  55.  
  56. char aChar;
  57. WindowPtr currentWindow;
  58. MenuHandle myMenus[editM+1];
  59. Rect dragRect, growRect;
  60. long newSize;
  61. Boolean doneFlag;
  62. EventRecord event;
  63. WindowPtr whichWindow;
  64. RGBColor pixColor;
  65. short i, j, k;
  66. PaletteHandle palH;
  67. DialogPtr dPtr;
  68. short doneDlg;
  69. OSErr err;
  70. SysEnvRec envRec;
  71.  
  72. Rect copyRect;
  73. GWorldPtr wallyWorld;
  74. GDHandle savedDevice;
  75. CGrafPtr savedPort;
  76.  
  77. double PowerOfN (double x, short r) {
  78.     double ans;
  79.     
  80.     ans = 1.0;
  81.     while (r-- > 0) ans *= x;
  82.     return ans;
  83. }
  84.  
  85. double fx, fy, fz;
  86.  
  87. short CalcVolumeData (short i, short j, short k) {
  88.     long x, y, z;
  89.     
  90.     fx = -(double)(i - halfVolSize);
  91.     fy = -(double)(j - halfVolSize);
  92.     fz = -(double)(k - halfVolSize);
  93.     if ((fx * fx + fy * fy + fz * fz) <= volumeMag) return 1;
  94.     else return 0;
  95. }
  96.  
  97. void DoColor (short i, short j, short k, RGBColor *RGBVal) {
  98.     double n_dot_h, n_dot_l, n_dot_h2, n_dot_l2, shade;
  99.     unsigned short color;
  100.     
  101.     if (CalcVolumeData (i, j, k)) {
  102.         n_dot_l = (fx + fy + fz)/sqrt3r;
  103.         n_dot_h = (fx + fy + 2.7321*fz)/rsqrt6;
  104.         shade = light*ambientReflCoef+(light/((double)(k)+depthCueCoef)*(diffReflCoef*n_dot_l+specReflCoef*PowerOfN (n_dot_h, highlightCoef)));
  105.  
  106.         /* second light source */
  107.         n_dot_l2 = -fx/sphere_r;
  108.         n_dot_h2 = (-fx + fz)/(1.4142*sphere_r);
  109.         shade += light/((double)(k)+depthCueCoef)*(diffReflCoef*n_dot_l2+specReflCoef*PowerOfN (n_dot_h2, highlightCoef));
  110.  
  111.         color = (unsigned short)(shade * 65534.0);
  112.         RGBVal->red = color;
  113.         RGBVal->green = color;
  114.         RGBVal->blue = color;
  115.     }
  116.     else {
  117.         RGBVal->red = 0;
  118.         RGBVal->green = 0;
  119.         RGBVal->blue = 0;
  120.     };
  121. }
  122.  
  123. void OpenWindow (void) {
  124.     currentWindow = (WindowPtr)GetNewCWindow(windowRscr, NULL, (Ptr)-1);
  125.     SetPort(currentWindow);
  126.     SizeWindow(currentWindow, volSize + 25, volSize + 25, 1);
  127.     SetWTitle(currentWindow, &"\pVol3D");
  128.     ShowWindow(currentWindow);
  129. }
  130.  
  131. void Init (void) {
  132.     short i, j, k;
  133.  
  134.     InitGraf(&thePort);
  135.     InitFonts ();
  136.     FlushEvents (everyEvent, 0);
  137.     InitWindows ();
  138.     InitMenus ();
  139.     TEInit ();
  140.     InitDialogs (NULL);
  141.  
  142.     myMenus[appleM] = GetMenu(appleID);
  143.     AddResMenu(myMenus[appleM], 'DRVR');
  144.  
  145.     myMenus[fileM] = GetMenu(fileID);
  146.     myMenus[editM] = GetMenu(editID);
  147.  
  148.     for (i=appleM;i<=editM;i++) InsertMenu(myMenus[i], 0);
  149.  
  150.     DrawMenuBar ();
  151.  
  152.     SetRect(&dragRect, 30, 20, screenBits.bounds.right - 10, screenBits.bounds.bottom - 30);
  153.     SetRect(&growRect, 50, 50, screenBits.bounds.right - 20, screenBits.bounds.bottom - 50);
  154.  
  155.     doneFlag = 0;
  156.     err = SysEnvirons(1, &envRec);
  157.     if (!envRec.hasColorQD) doneFlag = 1;
  158.     else {
  159.         OpenWindow ();
  160.         palH = GetNewPalette (paletteRscr);
  161.         if (palH == NULL) {
  162.             doneFlag = 1;
  163.         }
  164.         else {
  165.             SetPalette (currentWindow, palH, 1);
  166.         }
  167.         
  168.         /* set up the offscreen drawing port */
  169.         GetGWorld (&savedPort, &savedDevice);
  170.         SetRect (©Rect, 0, 0, volSize-1, volSize-1);
  171.         LocalToGlobal (©Rect.top);
  172.         LocalToGlobal (©Rect.bottom);
  173.         err = NewGWorld (&wallyWorld, 0, ©Rect, NULL, NULL, 0);
  174.         GlobalToLocal (©Rect.top);
  175.         GlobalToLocal (©Rect.bottom);
  176.  
  177.         if (err != noErr)
  178.             doneFlag = 1;
  179.         else {
  180.             SetGWorld (wallyWorld, NULL);
  181.             if (LockPixels (wallyWorld->portPixMap)) {
  182.                 /* draw off screen here */
  183.                 for(i=0;i<volSize;i++) 
  184.                     for (j=0;j<volSize;j++) {
  185.                         k = 0;
  186.                         do {
  187.                             DoColor(i, j, k, &pixColor);
  188.                             k++;
  189.                         } while ((pixColor.red == 0) & (k < volSize));
  190.                         SetCPixel (i, j, &pixColor);
  191.                     }
  192.                 UnlockPixels (wallyWorld->portPixMap);
  193.             }
  194.             else doneFlag = 1;
  195.     
  196.             /* the drawing is done set the current port back to the display window */
  197.         }
  198.         SetGWorld (savedPort, savedDevice);
  199.     }
  200. }
  201.  
  202. void DoAboutBox (void) {
  203.  
  204.     dPtr = GetNewDialog (aboutDialog, NULL, (Ptr)-1);
  205.     do
  206.         ModalDialog(NULL, &doneDlg);
  207.     while (!doneDlg);
  208.     DisposDialog(dPtr);
  209. }
  210.  
  211. void CleanUp (void) {
  212.     
  213.     HideWindow (currentWindow);
  214.     DisposeGWorld (wallyWorld);
  215.     DisposePalette (palH);
  216.     DisposeWindow (currentWindow);
  217.     doneFlag = 1;
  218. }
  219.  
  220. void DoCommand (long menuResult) {
  221.     short menuID, menuItem;
  222.     Str255 daName;
  223.     short daErr;
  224.  
  225.     menuItem = LoWord (menuResult);
  226.     menuID = HiWord (menuResult);
  227.  
  228.     switch (menuID) {
  229.         case appleID: 
  230.             if (menuItem == appleAbout) DoAboutBox ();
  231.             else {
  232.                 GetItem(myMenus[appleM], menuItem, daName);
  233.                 daErr = OpenDeskAcc(daName);
  234.                 if (currentWindow) SetPort (currentWindow);
  235.             }
  236.             break;
  237.         case fileID: 
  238.             switch (menuItem) { 
  239.                 case fileQuit: 
  240.                     CleanUp ();
  241.                     break;
  242.             }
  243.             break;
  244.     }
  245.     HiliteMenu(0);
  246. }
  247.  
  248. void DoEvent (void) {
  249.  
  250.     switch (event.what) {
  251.         case mouseDown: 
  252.             switch (FindWindow(event.where, &whichWindow)) {
  253.                 case inMenuBar: 
  254.                     DoCommand(MenuSelect(event.where));
  255.                     break;
  256.                 case inSysWindow: 
  257.                     SystemClick(&event, whichWindow);
  258.                     break;
  259.                 case inDrag: 
  260.                     DragWindow(whichWindow, event.where, &dragRect);
  261.                     break;
  262.                 case inGrow: 
  263.                     newSize = GrowWindow(whichWindow, event.where, &growRect);
  264.                     SizeWindow(whichWindow, LoWord(newSize), HiWord(newSize), 1);
  265.                     InvalRect(¤tWindow->portRect);
  266.                     break;
  267.                 case inGoAway: 
  268.                     if (TrackGoAway(whichWindow, event.where)) CleanUp ();
  269.                     break;
  270.             } /* case findwindow (...) */
  271.             break;
  272.         case keyDown:
  273.         case autoKey: 
  274.             aChar = (char)(BitAnd (event.message, charCodeMask));
  275.             if (BitAnd (event.modifiers, cmdKey)) DoCommand(MenuKey(aChar));
  276.             break;
  277.         case activateEvt: 
  278.             if (BitAnd(event.modifiers, activeFlag)) DisableItem(myMenus[editM], 0);
  279.             else EnableItem(myMenus[editM], 0);
  280.             break;
  281.  
  282.         case updateEvt: 
  283.             BeginUpdate(currentWindow);
  284.             EraseRect(¤tWindow->portRect);
  285.             DrawGrowIcon(currentWindow);
  286.             InsetRect (¤tWindow->portRect, 8, 8);
  287.             OffsetRect (¤tWindow->portRect, -8, -8);
  288.  
  289.             if (LockPixels (wallyWorld->portPixMap)) {
  290.                 CopyBits(&wallyWorld->portPixMap, ¤tWindow->portBits, ©Rect, ¤tWindow->portRect, srcCopy, NULL);
  291.                 UnlockPixels (wallyWorld->portPixMap);
  292.             }
  293.             
  294.             OffsetRect (¤tWindow->portRect, 8, 8);
  295.             InsetRect (¤tWindow->portRect, -8, -8);
  296.             EndUpdate(currentWindow);
  297.             break;
  298.     }
  299. }
  300.  
  301. void main (void) {
  302.     currentWindow = NULL;
  303.     Init ();
  304.     InitCursor ();
  305.  
  306.     do {
  307.         if (WaitNextEvent (everyEvent, &event, sleepTicks, NULL)) DoEvent ();
  308.     } while (!doneFlag);
  309. }
  310.  
  311.